package rpc;

import java.net.*;
import java.util.*;
import net.hangar5.xmlrpc.*;
import java.awt.event.*;
import java.io.*;

public class I2cRpcServer implements Serializable
{
    private static final int minWorkers = 4;  // these are the TINI values, for full scale JVMs the value should be larger
    private static final int maxWorkers = 8;  // these are the TINI values, for full scale JVMs the value should be larger
    private static final int maxKeepAlives = 8;  // these are the TINI values, for full scale JVMs the value should be larger
    private static final int workerIdleLife = 120000; // two minutes
    private static final int socketReadTimeout = 120000; // two minutes

    private transient Vector actionListeners;

    //serveur RPC tournant dans son thread propre
    private  RpcServer server;
    private  Thread threadServer;
    private int port = 80;
    private ServerSocket ss;
    private byte[] trame;

    public I2cRpcServer()
    {
	initServer();
    }

    public int getPortServer()
    {
	return  port;
    }

    public void setPortServer(int port)
    {
	this.port = port;
	shutDownServer();
	initServer();
    }

    private void initServer()
    {
	try
	{
	    ss = new ServerSocket(port);
	    System.out.println("ss adresse: " + ss.getInetAddress().getHostAddress());
	    server = new RpcServer( ss , minWorkers, maxWorkers, maxKeepAlives, workerIdleLife, socketReadTimeout);
	    Dispatcher dispatcher = server.getDispatcher();
	    //dispatcher.setVerbose(false);
	    addMethods(dispatcher);
	    threadServer = new Thread(server);
	    threadServer.setDaemon(false);
	    threadServer.start();
	}
	catch (Exception e)
	{
	    System.out.println("creation server impossible: " + e.toString());
	}
    }


    public void shutDownServer()
    {
	try
	{
	    server.shutDown();
	}
	catch (IOException io)
	{
	    System.out.println("erreur shutdown server: " + io.toString());
	}

    }


    //**************************************************************************
    //                 en provenance du superviseur
    //**************************************************************************

    public void addMethods( Dispatcher dispatcher )
    {
	IMethod m;
	m = new doTrame();
	dispatcher.addMethod( m );

    }

    public class doTrame extends Method
    {
	private static final String strName = "doTrame";
	public String getName()
	{
	    return strName;
	}

	public Object execute(Vector vParams) throws RpcException
	{
	    Object oRet;
	    try
	    {
		trame = ((byte[])vParams.elementAt(0));
		doTrameEvent();
		oRet = trame;
	    }
	    catch( ClassCastException x )
	    {
		oRet = null;
		throw new RpcException( RpcException.BADPARAMTYPE );
	    }
	    return oRet;
	}
    }


    private void doTrameEvent()
    {
	ActionEvent actionEvt = new ActionEvent(this, 0, "trameI2c");
	fireActionPerformed(actionEvt);
    }

    public synchronized void removeActionListener(ActionListener l)
    {
	if (actionListeners != null && actionListeners.contains(l))
	{
	    Vector v = (Vector) actionListeners.clone();
	    v.removeElement(l);
	    actionListeners = v;
	}
    }

    public synchronized void addActionListener(ActionListener l)
    {
	Vector v = actionListeners == null ? new Vector(2) : (Vector) actionListeners.clone();
	if (!v.contains(l))
	{
	    v.addElement(l);
	    actionListeners = v;
	}
    }

    protected void fireActionPerformed(ActionEvent e)
    {
	if (actionListeners != null)
	{
	    Vector listeners = actionListeners;
	    int count = listeners.size();
	    for (int i = 0; i < count; i++)
	    {
		((ActionListener) listeners.elementAt(i)).actionPerformed(e);
	    }
	}
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
	oos.defaultWriteObject();
    }
    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
	ois.defaultReadObject();
    }

}